// 版权所有 Epic Games, Inc. 保留所有权利。
#pragma once

#include "Abilities/Tasks/AbilityTask.h"
#include "Engine/CollisionProfile.h"
#include "Interaction/InteractionOption.h"

#include "AbilityTask_WaitForInteractableTargets.generated.h"

class AActor;
class IInteractableTarget;
class UObject;
class UWorld;
struct FCollisionQueryParams;
struct FHitResult;
struct FInteractionQuery;
template <typename InterfaceType> class TScriptInterface;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FInteractableObjectsChangedEvent, const TArray<FInteractionOption>&, InteractableOptions); // 可交互对象改变事件委托

UCLASS(Abstract)
class UAbilityTask_WaitForInteractableTargets : public UAbilityTask
{
	GENERATED_UCLASS_BODY()

public:
	UPROPERTY(BlueprintAssignable)
	FInteractableObjectsChangedEvent InteractableObjectsChanged; // 可交互对象改变事件

protected:

	/**
	 * 执行射线检测
	 * @param OutHitResult 输出命中结果
	 * @param World 世界
	 * @param Start 起始点
	 * @param End 结束点
	 * @param ProfileName 碰撞配置文件名称
	 * @param Params 碰撞查询参数
	 */
	static void LineTrace(FHitResult& OutHitResult, const UWorld* World, const FVector& Start, const FVector& End, FName ProfileName, const FCollisionQueryParams Params);

	/**
	 * 使用玩家控制器进行瞄准
	 * @param InSourceActor 源角色
	 * @param Params 碰撞查询参数
	 * @param TraceStart 追踪起始点
	 * @param MaxRange 最大范围
	 * @param OutTraceEnd 输出追踪结束点
	 * @param bIgnorePitch 是否忽略俯仰角
	 */
	void AimWithPlayerController(const AActor* InSourceActor, FCollisionQueryParams Params, const FVector& TraceStart, float MaxRange, FVector& OutTraceEnd, bool bIgnorePitch = false) const;

	/**
	 * 将相机射线裁剪到能力范围
	 * @param CameraLocation 相机位置
	 * @param CameraDirection 相机方向
	 * @param AbilityCenter 能力中心
	 * @param AbilityRange 能力范围
	 * @param ClippedPosition 裁剪后的位置
	 * @return 是否成功裁剪
	 */
	static bool ClipCameraRayToAbilityRange(FVector CameraLocation, FVector CameraDirection, FVector AbilityCenter, float AbilityRange, FVector& ClippedPosition);

	/**
	 * 更新可交互选项
	 * @param InteractQuery 交互查询
	 * @param InteractableTargets 可交互目标数组
	 */
	void UpdateInteractableOptions(const FInteractionQuery& InteractQuery, const TArray<TScriptInterface<IInteractableTarget>>& InteractableTargets);

	FCollisionProfileName TraceProfile; // 追踪配置文件名称

	bool bTraceAffectsAimPitch = true; // 追踪是否影响瞄准俯仰角

	TArray<FInteractionOption> CurrentOptions; // 当前交互选项数组
};